package org.xx.armory.db.junit;

import org.xx.armory.db.junit.DbUnitHelper.Column;
import org.xx.armory.db.junit.DbUnitHelper.Row;
import org.xx.armory.xml.IndentedXMLStreamWriter;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.OutputStream;

/**
 * 向XML文件中写入数据库记录的类
 *
 * @author Haart
 */
public final class DbUnitTableWriter {
    private static final String ROOT_ELEMENT_NAME = "rows";
    private static final String ROW_ELEMENT_NAME = "row";

    private DbUnitTableWriter() {
        throw new UnsupportedOperationException();
    }

    /**
     * 向XML文件中写入数据库记录的类
     *
     * @param tableName
     *         数据库表名。
     * @param columns
     *         需要写入的列名数组。
     * @param rows
     *         需要写入的记录。
     * @param stream
     *         包含XML文件的流
     * @throws XMLStreamException
     *         如果写入过程中出现错误。
     */
    public static void write(
            String tableName,
            Column[] columns,
            Row[] rows,
            OutputStream stream
    )
            throws XMLStreamException {
        XMLStreamWriter writer = null;

        try {
            writer = new IndentedXMLStreamWriter(XMLOutputFactory.newFactory()
                                                                 .createXMLStreamWriter(stream));

            writer.writeStartDocument("utf-8", "1.0");
            writer.writeStartElement(ROOT_ELEMENT_NAME);

            if (rows != null) {
                for (int i = 0; i < rows.length; ++i) {
                    writeRow(writer, i, columns, rows[i]);
                }
            }

            writer.writeEndElement();
            writer.writeEndDocument();
        } finally {
            if (writer != null) {
                writer.flush();
                writer.close();
            }
        }
    }

    /**
     * 向XML文件中写入一条记录。
     *
     * @param writer
     *         用于写入XML文件的XML流写入器。
     * @param rowIndex
     *         行序号。
     * @param columns
     *         需要写入的列名数组。
     * @param row
     *         需要写入的记录。
     * @throws XMLStreamException
     *         如果写入过程中出现错误。
     */
    private static void writeRow(
            XMLStreamWriter writer,
            int rowIndex,
            Column[] columns,
            Row row
    )
            throws XMLStreamException {
        writer.writeEmptyElement(ROW_ELEMENT_NAME);
        for (int i = 0; i < columns.length; ++i) {
            writer.writeAttribute(columns[i].getName(), row.get(i));
        }
    }
}
